﻿
namespace TrivialPurfuit.Business
{
    public class GamePiece : BindableObject
    {
        ///////////////////////////////////////////////////////////////////////////////////////////
        // Constants and Static stuff
        ///////////////////////////////////////////////////////////////////////////////////////////
        public const int PIECE_OFFSET = 10;

        ///////////////////////////////////////////////////////////////////////////////////////////
        // Properties
        ///////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Gets the name of the player the game piece belongs to.
        /// </summary>
        private string _PlayerName;
        public string PlayerName
        {
            get
            {
                return this._PlayerName;
            }

            set
            {
                this._PlayerName = value;
                this.RaisePropertyChanged("PlayerName");
            }
        }

        /// <summary>
        /// Gets and sets the color of the game piece.
        /// </summary>
        private string _PieceColor;
        public string PieceColor
        {
            get
            {
                return this._PieceColor;
            }

            set
            {
                this._PieceColor = value;
                this.RaisePropertyChanged("PieceColor");
            }
        }

        private bool _Highlight;
        public bool Highlight
        {
            get
            {
                return _Highlight;
            }

            set
            {
                this._Highlight = value;
                this.RaisePropertyChanged("Highlight");
            }
        }

        /// <summary>
        /// Indicates if this piece has the "cake" slice assosiated with the 1 catagory.
        /// </summary>
        private bool _HasChip1;
        public bool HasChip1
        {
            get
            {
                return this._HasChip1;
            }

            set
            {
                this._HasChip1 = value;
                this.RaisePropertyChanged("HasChip1");
            }
        }

        /// <summary>
        /// Indicates if this piece has the "cake" slice assosiated with the 2 catagory.
        /// </summary>
        private bool _HasChip2;
        public bool HasChip2
        {
            get
            {
                return this._HasChip2;
            }

            set
            {
                this._HasChip2 = value;
                this.RaisePropertyChanged("HasChip2");
            }
        }

        /// <summary>
        /// Indicates if this piece has the "cake" slice assosiated with the 3 catagory.
        /// </summary>
        private bool _HasChip3;
        public bool HasChip3
        {
            get
            {
                return this._HasChip3;
            }

            set
            {
                this._HasChip3 = value;
                this.RaisePropertyChanged("HasChip3");
            }
        }

        /// <summary>
        /// Indicates if this piece has the "cake" slice assosiated with the 4 catagory.
        /// </summary>
        private bool _HasChip4;
        public bool HasChip4
        {
            get
            {
                return this._HasChip4;
            }

            set
            {
                this._HasChip4 = value;
                this.RaisePropertyChanged("HasChip4");
            }
        }

        /// <summary>
        /// Gets or sets the game Pieces board space.
        /// </summary>
        private int _SpaceNumber;
        public int SpaceNumber 
        {
            get
            {
                return this._SpaceNumber;
            }

            set
            {
                this._SpaceNumber = BoardMap.getAValidSpace(value);

                if (this.SpaceNumber == BoardMap.NULL_SPACE_NUMBER)
                    this.takePieceOffTheBoard();
                else
                    this.centerPieceOnBoardSpace();

                this.RaisePropertyChanged("SpaceNumber");
                this.RaisePropertyChanged("PixelPositionX");
                this.RaisePropertyChanged("PixelPositionY");
            }
        }

        /// <summary>
        /// Gets the column this piece occupies of the of boards grid. This is updated when the space position is set.
        /// </summary>
        public int PixelPositionX {get; private set; }

        /// <summary>
        /// Gets the row this piece occupies of the of boards grid. This is updated when the space position is set.
        /// </summary>
        public int PixelPositionY { get; private set; }

        public GamePiece(string playerName, string pieceColor)
        {
            this._PlayerName = playerName;
            this._PieceColor = pieceColor;

            this._SpaceNumber = BoardMap.NULL_SPACE_NUMBER;
            this.takePieceOffTheBoard();

            this._HasChip1 = false;
            this._HasChip2 = false;
            this._HasChip3 = false;
            this._HasChip4 = false;
            this._Highlight = false;
        }

        private void centerPieceOnBoardSpace()
        {
            int spaceSize = GameBoard.Instance.Spaces[_SpaceNumber].Size;
            int spacePositionX = GameBoard.Instance.Spaces[_SpaceNumber].PixelPositionX;
            int spacePositionY = GameBoard.Instance.Spaces[_SpaceNumber].PixelPositionY;

            this.PixelPositionX = spacePositionX + (spaceSize / 2);
            this.PixelPositionY = spacePositionY + (spaceSize / 2);

            int otherPieces = howManyOtherPiecesOnThisSpace();

            if (otherPieces == 1 )
                this.PixelPositionX += PIECE_OFFSET;

            else if (otherPieces == 2)
                this.PixelPositionX -= PIECE_OFFSET;

            else if (otherPieces == 3)
                this.PixelPositionY -= PIECE_OFFSET;
        }

        private int howManyOtherPiecesOnThisSpace()
        {
            int count = 0;

            foreach (GamePiece piece in GameBoard.Instance.Pieces)
            {
                if (piece != this && piece.SpaceNumber == this.SpaceNumber)
                    count++;
            }

            return count;
        }

        private void takePieceOffTheBoard()
        {
            this.PixelPositionX = BoardMap.OFF_THE_BOARD_DISTANCE;
            this.PixelPositionY = BoardMap.OFF_THE_BOARD_DISTANCE;
        }

        public bool hasAllChips()
        {
            bool result = false;

            if (HasChip1 && HasChip2 && HasChip3 && HasChip4)
                result = true;

            return result;
        }

        public void clearChips()
        {
            this.HasChip1 = false;
            this.HasChip2 = false;
            this.HasChip3 = false;
            this.HasChip4 = false;
        }

        public void giveCategoryChip(int categoryID)
        {
            if (categoryID == GameBoard.Instance.Category1.ID)
                this.HasChip1 = true;

            else if (categoryID == GameBoard.Instance.Category2.ID)
                this.HasChip2 = true;

            else if (categoryID == GameBoard.Instance.Category3.ID)
                this.HasChip3 = true;

            else if (categoryID == GameBoard.Instance.Category4.ID)
                this.HasChip4 = true;
        }
    }
}
